﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NGIS.Data.Schema
{
    public enum ESchemaNodeType
    {
        EDTKT_INT = 2,				//!<integer
        EDTKT_REAL = 4,				//!<float with 64bit precise
        EDTKT_STRING = 8,			//!<a string with NULL terminated
        EDTKT_VECTOR2 = 16,		//!<2 dimensions vector with x and y
        EDTKT_VECTOR3 = 32,		//!<3 dimensions vector with x, y and z
        EDTKT_VECTOR4 = 64,		//!<4 dimensions vector with x, y, z and w
        
        EDTKT_NODE = 128,			//!<a no-constraints node container
        EDTKT_LIST = 256,				//!<a container with same structure node
        EDTKT_MAP = 512,				//!<a k-v map container
        EDTKT_TABLE = 1024,			//!<a data table container

        EDTKT_INT_LIST = 2 | 256,
        EDTKT_REAL_LIST = 4 | 256,
        EDTKT_STRING_LIST = 8 | 256,
        EDTKT_VECTOR2_LIST = 16 | 256,
        EDTKT_VECTOR3_LIST = 32 | 256,
        EDTKT_VECTOR4_LIST = 64 | 256
    }



    public class UdxNodeDescription
    {
        protected ESchemaNodeType mKernelType;
        protected string mNodeInfo;
        protected string mConceptTag;
        protected string mUnitTag;
        protected string mDimensionTag;
        protected string mSpatialRefTag;
        protected string mDataTemplateTag;

        public UdxNodeDescription(ESchemaNodeType pType, string pDescription)
        {
            mKernelType = pType;
            mNodeInfo = pDescription;
            mConceptTag = "";
            mUnitTag = "";
            mDimensionTag = "";
            mSpatialRefTag = "";
            mDataTemplateTag = "";
        }

        public static string SchemaNodeType2String(ESchemaNodeType pType)
        {
            if (pType == ESchemaNodeType.EDTKT_INT)
                return "DTKT_INT";
            else if (pType == ESchemaNodeType.EDTKT_REAL)
                return "DTKT_REAL";
            else if (pType == ESchemaNodeType.EDTKT_VECTOR2)
                return "DTKT_VECTOR2D";
            else if (pType == ESchemaNodeType.EDTKT_VECTOR3)
                return "DTKT_VECTOR3D";
            else if (pType == ESchemaNodeType.EDTKT_VECTOR4)
                return "DTKT_VECTOR4D";
            else if (pType == ESchemaNodeType.EDTKT_STRING)
                return "DTKT_STRING";
            else if (pType == (ESchemaNodeType.EDTKT_INT | ESchemaNodeType.EDTKT_LIST))
                return "DTKT_INT | DTKT_LIST";
            else if (pType == (ESchemaNodeType.EDTKT_REAL | ESchemaNodeType.EDTKT_LIST))
                return "DTKT_REAL | DTKT_LIST";
            else if (pType == (ESchemaNodeType.EDTKT_VECTOR2 | ESchemaNodeType.EDTKT_LIST))
                return "DTKT_VECTOR2D | DTKT_LIST";
            else if (pType == (ESchemaNodeType.EDTKT_VECTOR3 | ESchemaNodeType.EDTKT_LIST))
                return "DTKT_VECTOR3D | DTKT_LIST";
            else if (pType == (ESchemaNodeType.EDTKT_VECTOR4 | ESchemaNodeType.EDTKT_LIST))
                return "DTKT_VECTOR4D | DTKT_LIST";
            else if (pType == (ESchemaNodeType.EDTKT_STRING | ESchemaNodeType.EDTKT_LIST))
                return "DTKT_STRING | DTKT_LIST";
            else if (pType == ESchemaNodeType.EDTKT_NODE)
                return "DTKT_ANY";
            else if (pType == ESchemaNodeType.EDTKT_LIST)
                return "DTKT_LIST";
            else if (pType == ESchemaNodeType.EDTKT_MAP)
                return "DTKT_MAP";
            else if (pType == ESchemaNodeType.EDTKT_TABLE)
                return "DTKT_TABLE";
            return "DTKT_ANY";
        }

        public static ESchemaNodeType String2SchemaNodeType(string pType)
        {
            string pTypeStr = pType;
            ESchemaNodeType pNodeType = ESchemaNodeType.EDTKT_NODE;
            if (pTypeStr == "DTKT_INT")
                pNodeType = ESchemaNodeType.EDTKT_INT;
            else if (pTypeStr == "DTKT_REAL")
                pNodeType = ESchemaNodeType.EDTKT_REAL;
            else if (pTypeStr == "DTKT_VECTOR2D")
                pNodeType = ESchemaNodeType.EDTKT_VECTOR2;
            else if (pTypeStr == "DTKT_VECTOR3D")
                pNodeType = ESchemaNodeType.EDTKT_VECTOR3;
            else if (pTypeStr == "DTKT_VECTOR4D")
                pNodeType = ESchemaNodeType.EDTKT_VECTOR4;
            else if (pTypeStr == "DTKT_STRING")
                pNodeType = ESchemaNodeType.EDTKT_STRING;
            else if (pTypeStr == "DTKT_INT | DTKT_LIST")
                pNodeType = (ESchemaNodeType)(ESchemaNodeType.EDTKT_INT | ESchemaNodeType.EDTKT_LIST);
            else if (pTypeStr == "DTKT_REAL | DTKT_LIST")
                pNodeType = (ESchemaNodeType)(ESchemaNodeType.EDTKT_REAL | ESchemaNodeType.EDTKT_LIST);
            else if (pTypeStr == "DTKT_VECTOR2D | DTKT_LIST")
                pNodeType = (ESchemaNodeType)(ESchemaNodeType.EDTKT_VECTOR2 | ESchemaNodeType.EDTKT_LIST);
            else if (pTypeStr == "DTKT_VECTOR3D | DTKT_LIST")
                pNodeType = (ESchemaNodeType)(ESchemaNodeType.EDTKT_VECTOR3 | ESchemaNodeType.EDTKT_LIST);
            else if (pTypeStr == "DTKT_VECTOR4D | DTKT_LIST")
                pNodeType = (ESchemaNodeType)(ESchemaNodeType.EDTKT_VECTOR4 | ESchemaNodeType.EDTKT_LIST);
            else if (pTypeStr == "DTKT_STRING | DTKT_LIST")
                pNodeType = (ESchemaNodeType)(ESchemaNodeType.EDTKT_STRING | ESchemaNodeType.EDTKT_LIST);
            else if (pTypeStr == "DTKT_ANY")
                pNodeType = ESchemaNodeType.EDTKT_NODE;
            else if (pTypeStr == "DTKT_LIST")
                pNodeType = ESchemaNodeType.EDTKT_LIST;
            else if (pTypeStr == "DTKT_MAP")
                pNodeType = ESchemaNodeType.EDTKT_MAP;
            else if (pTypeStr == "DTKT_TABLE")
                pNodeType = ESchemaNodeType.EDTKT_TABLE;

            return pNodeType;
        }

        public ESchemaNodeType getKernelType()
        {
            return mKernelType;
        }

        public bool modifyKernelType(ESchemaNodeType pKernelType)
        {
            if (mKernelType == pKernelType) return false;
            mKernelType = pKernelType;
            return true;
        }

        public string getNodeDescription()
        {
            return mNodeInfo;
        }

        public bool modifyNodeDescription(string pNodeInfo)
        {
            if (mNodeInfo == pNodeInfo) return false;
            mNodeInfo = pNodeInfo;
            return true;
        }

        //////////////////////////////////////////////////////////////////////////
        public string getConceptTag()
        {
            return mConceptTag;
        }

        public bool modifyConceptTag(string pTag)
        {
            if (mConceptTag == pTag) return false;
            mConceptTag = pTag;
            return true;
        }

        public string getUnitTag()
        {
            return mUnitTag;
        }

        public bool modifyUnitTag(string pTag)
        {
            if (mUnitTag == pTag) return false;
            mUnitTag = pTag;
            return true;
        }

        public string getDimensionTag()
        {
            return mDimensionTag;
        }

        public bool modifyDimensionTag(string pTag)
        {
            if (mDimensionTag == pTag) return false;
            mDimensionTag = pTag;
            return true;
        }

        public string getSpatialReferencefTag()
        {
            return mSpatialRefTag;
        }

        public bool modifySpatialReferenceTag(string pTag)
        {
            if (mSpatialRefTag == pTag) return false;
            mSpatialRefTag = pTag;
            return true;
        }

        public string getDataTemplateTag()
        {
            return mDataTemplateTag;
        }

        public bool modifyDataTemplateTag(string pTag)
        {
            if (mDataTemplateTag == pTag) return false;
            mDataTemplateTag = pTag;
            return true;
        }
    };

}
